package com.xcy.quickhand.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xcy.quickhand.Constant;
import com.xcy.quickhand.mapper.AuthorInfoMapper;
import com.xcy.quickhand.mapper.VideoMapper;
import com.xcy.quickhand.model.AuthorInfo;
import com.xcy.quickhand.model.Video;
import com.xcy.quickhand.service.VideoService;
import com.xcy.quickhand.spider.CrawlVideoUtils;
import com.xcy.quickhand.util.redis.HttpUtil;
import com.xcy.quickhand.util.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xcy
 * @version V1.0
 * @description
 * @date 2023/2/11 21:21
 */
@Service
public class VideoServiceImpl implements VideoService {

    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private AuthorInfoMapper authorInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Integer saveVideo(String cookie, String userId) {

        List<Video> videoList = CrawlVideoUtils.crawlVideoListByAuthorId(cookie, userId);
        if (CollectionUtil.isEmpty(videoList)) {
            return 0;
        }

        // 过滤掉已经在数据库存在的视频
        List<Video> videos = filterVideo(videoList);
        // 存入数据库
        if (CollectionUtil.isNotEmpty(videos)) {
            videoMapper.batchInsert(videos);
        }
        // 存入redis中
        save2RedisMap(videos);

        return 1;
    }

    private void save2RedisMap(List<Video> videos) {
        // 拼接redis中hash (作者id_视频id,视频id)
        Map<String, String> videoUrlMap = new HashMap<>();
        videos.stream().forEach(v -> {
            videoUrlMap.put(v.getAuthorId() + "_" + v.getVideoId(), v.getVideoId());
        });
        new RedisUtil(redisTemplate).pipeLineHashData(Constant.VIDEO_URL, videoUrlMap);
    }

    private List<Video> filterVideo(List<Video> videoList) {
        // 找出videoList中视频在redis缓存中存在的视频集合
        List<String> videoRedisList = new RedisUtil(redisTemplate).getRedisVehicleCacheByPlateNumber(videoList);
        // 已经存在的重复数据集合[作者id_视频id]
        List<String> existVideoList = new ArrayList<>();

        // 将重复的数据从list中排除，并记录重复数据
        for (Iterator<Video> lt = videoList.iterator(); lt.hasNext(); ) {
            // 如果已经存在则丢弃
            Video vehicleInfo = lt.next();
            String key = vehicleInfo.getAuthorId() + "_" + vehicleInfo.getVideoId();
            String videoId = vehicleInfo.getVideoId();
            // 同一个视频从网页上获取到的视频地址可能会不一样，所以比对key，只要key一样就是重复
            if (videoRedisList.contains(videoId)) {
                existVideoList.add(key);
                lt.remove();
            }
        }
        if (!CollectionUtils.isEmpty(existVideoList)) {
            System.out.println("已存在的视频有：【" + existVideoList.size() + "】条，[作者id_视频id]如下：【" + JSONUtil.toJsonStr(existVideoList) + "】");
        }

        System.out.println("需要新增的视频条数：" + videoList.size());
        return videoList;
    }

    @Override
    public List<Video> selectList() {
        return videoMapper.selectAllUnDownloadList();
    }

    @Override
    public PageInfo selectByPage(Integer page, Integer rows) {
        PageHelper.startPage(page, rows);
        List<Video> articleList = videoMapper.selectAllUnDownloadList();
        PageInfo pageInfo = new PageInfo<>(articleList);
        return pageInfo;
    }

    @Override
    @Transactional
    public void downLoadVideo(String savePath, List<Video> list) {
        // 下载到本地
        list.stream().forEach(v -> HttpUtil.downVideo(v.getPhotoUrl(), v.getVideoCaption() + "_" + v.getVideoId(), savePath + "//" + v.getAuthorName() + "//"));

        // int a = 1/0;

        // 将已经下载的视频的标记更新为已下载
        videoMapper.updateHasDownLoadFlag(list.stream().map(Video::getId).collect(Collectors.toList()));
    }

    @Override
    public Integer saveAuthor(String cookie) {

        List<AuthorInfo> authorInfoList = CrawlVideoUtils.crawlAuthor(cookie);
        if (CollectionUtil.isEmpty(authorInfoList)) {
            return 0;
        }
        int i = authorInfoMapper.batchInsert(authorInfoList);
        return i;
    }
}
